home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1994…tember: Reference Library / Dev.CD Sep 94.toast / Periodicals / develop / develop Issue 9 / develop 9 code / Color on 1-Bit Devices / CreatePict.c < prev    next >
Encoding:
Text File  |  1992-01-06  |  9.3 KB  |  347 lines  |  [TEXT/KAHL]

  1.  
  2. /* Prototypes */
  3. PicHandle     CreatePICT2( PixMap *srcBits, Rect *srcRect, Rect *dstRect, short mode );
  4. void        PutOutPixMapSrcRectDstRectAndMode( PixMap *srcBits, short** inPicPtr, Rect *srcRect, Rect *dstRect, short mode );
  5. long        PutOutPackedIndexedPixData( PixMap *srcBits, short **picPtr );
  6. long        PutOutPackedDirectPixData( PixMap *srcBits, short **picPtr );
  7.  
  8. PicHandle 
  9. CreatePICT2(PixMap *srcBits, Rect *srcRect, Rect *dstRect, 
  10.     short mode)
  11. {
  12. PicHandle     myPic;
  13. short         myRowBytes;
  14. short         *picPtr;
  15. short         iii;
  16. long             handleSize;
  17.  
  18. #define CLIPSIZE 12
  19. #define PIXMAPRECSIZE 50
  20. #define HEADERSIZE 40
  21. #define MAXCOLORTABLESIZE 256*8+8
  22. #define OPCODEMISCSIZE 2+8+8+2    /* opcode+srcRect+dstRect+mode */
  23. #define ENDOFPICTSIZE 2
  24. #define PICSIZE PIXMAPRECSIZE + HEADERSIZE + MAXCOLORTABLESIZE +\
  25.     ENDOFPICTSIZE + OPCODEMISCSIZE + CLIPSIZE
  26.  
  27.     myRowBytes = srcBits->rowBytes & 0x3fff;
  28. /* Allocate worst-case memory scenario using PackBits packing. */
  29.     myPic = (PicHandle) NewHandle( PICSIZE + 
  30.         (long)((myRowBytes/127)+2+myRowBytes)*(long)(srcBits->bounds.bottom 
  31.         - srcBits->bounds.top));
  32.     if(!myPic)
  33.         return(0);
  34.  
  35. /* Skip picSize and put out picFrame (10 bytes). */
  36.     picPtr = (short *) (((long)*myPic) + 2);
  37.     *picPtr++ = dstRect->top;
  38.     *picPtr++ = dstRect->left;
  39.     *picPtr++ = dstRect->bottom;
  40.     *picPtr++ = dstRect->right;
  41.  
  42. /* Put out header (30 bytes). This could be done from a resource or
  43.     taken from an existing picture. */
  44.     *picPtr++ = 0x11;        /* Version opcode. */
  45.     *picPtr++ = 0x2ff;    /* Version number. */
  46.     *picPtr++ = 0xC00;    /* Header opcode. */
  47.     *picPtr++ = 0xFFFF;    /* Put out PICT header version. */
  48.     *picPtr++ = 0xFFFF;
  49. /* The rest of the header is ignored--0 it out. */
  50.     for(iii = 10; iii > 0; iii--)
  51.         *picPtr++ = 0;        /* Write out 24 bytes of 0. */
  52.  
  53. /* Put out current port's clip region. */
  54.     *picPtr++ = 0x01;
  55.     *picPtr++ = 0x0A;        /* Clip region only has bounds rectangle. */
  56.     *picPtr++ = (**thePort->clipRgn).rgnBBox.top;
  57.     *picPtr++ = (**thePort->clipRgn).rgnBBox.left;
  58.     *picPtr++ = (**thePort->clipRgn).rgnBBox.bottom;
  59.     *picPtr++ = (**thePort->clipRgn).rgnBBox.right;
  60.     
  61.     HLock(myPic);
  62.     if(srcBits->pixelType == RGBDirect)
  63.     {            /* Must be 32-bits/pixel */
  64.     /* Put out opCode $9A, DirectBitsRect. */
  65.         *picPtr++ = 0x9A;
  66.         *picPtr++ = 0;    /* BaseAddr for direct pixMaps is 0x000000FF. */
  67.         *picPtr++ = 0xFF;
  68.         PutOutPixMapSrcRectDstRectAndMode(srcBits, &picPtr, srcRect, 
  69.             dstRect, mode);
  70.         if(PutOutPackedDirectPixData(srcBits, &picPtr))        /* Nonzero 
  71.             indicates an error. */
  72.             goto errorExit;
  73.     }
  74.     else
  75.     {
  76.     /* Put out opCode $98, PackBitsRect. */
  77.         *picPtr++ = 0x98;
  78.         PutOutPixMapSrcRectDstRectAndMode(srcBits, &picPtr, srcRect,
  79.             dstRect, mode);
  80.         if(PutOutPackedIndexedPixData(srcBits, &picPtr))    /* Nonzero
  81.             indicates an error. */
  82.             goto errorExit;
  83.                             
  84.     }
  85.     HUnlock(myPic);
  86.     
  87. /* All done!  Put out end-of-picture opcode, $00FF. */
  88.     *picPtr++ = 0x00FF;
  89.  
  90. /* Size handle down to the amount actually used. */
  91.     handleSize = (long) picPtr - (long) *myPic;
  92.     SetHandleSize( myPic, handleSize );
  93.     /* Write out picture size. */
  94.     *((short *)*myPic) = (short) handleSize;
  95.     return(myPic);
  96.  
  97. errorExit:
  98.     DisposHandle(myPic);
  99.     return(0);
  100. }
  101.  
  102.  
  103. void
  104. PutOutPixMapSrcRectDstRectAndMode( PixMap *srcBits, short** inPicPtr, Rect *srcRect, 
  105.     Rect *dstRect, short mode )
  106. {
  107. short iii;
  108. short * picPtr = *inPicPtr;
  109. short myRowBytes = srcBits->rowBytes & 0x3fff;
  110.  
  111. /* put out pixMap */
  112.     *picPtr++ = srcBits->rowBytes | 0x8000;        /*always make PixMaps */
  113.     *picPtr++ = srcBits->bounds.top;    /* Bounds */
  114.     *picPtr++ = srcBits->bounds.left;
  115.     *picPtr++ = srcBits->bounds.bottom;
  116.     *picPtr++ = srcBits->bounds.right;
  117.     *picPtr++ = 0;    /* version number */
  118. /*
  119. ** Put out packing format:
  120. ** 0 is default indexed packing.
  121. ** 1 is no packing (rowBytes <  8 )
  122. ** 4 is default direct packing - run length encoded scan lines by component, red first.
  123. */
  124.     if( myRowBytes < 8 && myRowBytes > 0 )
  125.         *picPtr++ = 1;    /* packing format: unpacked */
  126.     else
  127.     {
  128.         if( srcBits->pixelType == RGBDirect )
  129.             *picPtr++ = 4;
  130.         else
  131.             *picPtr++ = 0;    /* packing format: standard */
  132.     }
  133.     
  134.     *picPtr++ = 0;    /* packed size */
  135.     *picPtr++ = 0;
  136.     *picPtr++ = 0x48;    /* horizontal resolution: $0048 0000 */
  137.     *picPtr++ = 0;
  138.     *picPtr++ = 0x48;    /* vertical resolution: $0048 0000 */
  139.     *picPtr++ = 0;
  140.  
  141. /* these fields are different for BitMap/PixMap */
  142.     if( srcBits->rowBytes < 0 )
  143.     {/* do PixMap */
  144.         *picPtr++ = srcBits->pixelType;
  145.         *picPtr++ = srcBits->pixelSize;    /* pixel size */
  146.         *picPtr++ = srcBits->cmpCount;    /* number of components */
  147.         *picPtr++ = srcBits->cmpSize;    /* size of each component */
  148.     }
  149.     else
  150.     {/* do BitMap */
  151.         *picPtr++ = 0;
  152.         *picPtr++ = 1;    /* pixel size */
  153.         *picPtr++ = 1;    /* number of components */
  154.         *picPtr++ = 1;    /* size of each component */
  155.     }
  156.  
  157.     *picPtr++ = 0;    /* offset to next plane */
  158.     *picPtr++ = 0;
  159.  
  160.     if( srcBits->pixelType == RGBDirect )
  161.     {
  162.         *picPtr++ = 0;    /* color table is nil for Direct pixmaps*/
  163.         *picPtr++ = 0;
  164.     }
  165.     else
  166.     {
  167.         *picPtr++ = (unsigned short) srcBits->pmTable>>16;    /* color table */
  168.         *picPtr++ = (unsigned short) srcBits->pmTable;
  169.     }
  170.     
  171.     *picPtr++ = 0;    /* reserved */
  172.     *picPtr++ = 0;
  173.  
  174. /* put out colortable if indexed pixmap*/
  175.     if( (srcBits->rowBytes < 0) && (srcBits->pmTable) && (srcBits->pixelType != RGBDirect) )
  176.     {
  177.     short* ctPtr = (short *) *(srcBits->pmTable);    /* Get ptr to color table */
  178.         *picPtr++ = *ctPtr++;    /* copy ctSeed */ 
  179.         *picPtr++ = *ctPtr++;
  180.         *picPtr++ = *ctPtr++; /* copy ctFlags */
  181.         iii = *ctPtr; 
  182.         *picPtr++ = *ctPtr++; /* copy ctSize */
  183.         for( ; iii >= 0; iii-- )
  184.         {/* put out all entries */
  185.             *picPtr++ = *ctPtr++;    /* pixel value */
  186.             *picPtr++ = *ctPtr++;    /* red */
  187.             *picPtr++ = *ctPtr++;    /* green */
  188.             *picPtr++ = *ctPtr++;    /* blue */
  189.         }
  190.     }
  191.     else
  192.     if( srcBits->pixelType != RGBDirect )
  193.     {
  194.         for( iii = 8; iii > 0; iii-- )
  195.             *picPtr++ = 0;    /* put out an empty color table: 8 words of 0 */
  196.     }
  197.  
  198. /* put out srcrect, dstrect, and mode */
  199.     *picPtr++ = srcRect->top;
  200.     *picPtr++ = srcRect->left;
  201.     *picPtr++ = srcRect->bottom;
  202.     *picPtr++ = srcRect->right;
  203.  
  204.     *picPtr++ = dstRect->top;
  205.     *picPtr++ = dstRect->left;
  206.     *picPtr++ = dstRect->bottom;
  207.     *picPtr++ = dstRect->right;
  208.  
  209.     *picPtr++ = mode;
  210.     *inPicPtr = picPtr;
  211. }
  212.  
  213. long
  214. PutOutPackedIndexedPixData( PixMap *srcBits, short **picPtr )
  215. {
  216. Ptr    srcPtr = srcBits->baseAddr;
  217. Ptr    dstPtr;
  218. Ptr    packBuf;
  219. Ptr    tempPicPtr = (char*) *picPtr;
  220. short packedSize;
  221. short iii, jjj;
  222. unsigned short    myRowBytes;    
  223.  
  224.     myRowBytes = srcBits->rowBytes & 0x3fff;
  225.  
  226.     /* put out PixData */
  227.     if( myRowBytes < 8 )
  228.     { /* no packing */
  229.     short * pixMapPtr = (short *) srcBits->baseAddr;
  230.         for( iii = (myRowBytes*(srcBits->bounds.bottom - srcBits->bounds.top))/2; iii > 0; iii-- )
  231.             *tempPicPtr++ = *pixMapPtr++;
  232.         return( 0 );
  233.     }
  234.     
  235.     packBuf = (Ptr)NewPtr( myRowBytes * 2 );
  236.     if( !packBuf )
  237.         return( -1 );
  238.  
  239. /* Must use only byte accesses to avoid address errors on 68K class machines */
  240.  
  241.     for( iii = srcBits->bounds.bottom - srcBits->bounds.top; iii > 0; iii-- )
  242.     {
  243.         dstPtr = packBuf;
  244.         PackBits( &srcPtr, &dstPtr, myRowBytes );
  245.         packedSize = (long)dstPtr - (long)packBuf;
  246.         if( myRowBytes <= 250 )
  247.         { /* put a byte to the picture */
  248.             *tempPicPtr++ = (unsigned char)packedSize;
  249.         }
  250.         else
  251.         { /* put a word to the picture */
  252.             *tempPicPtr++ = (unsigned char)(packedSize>>8);
  253.             *tempPicPtr++ = (unsigned char)packedSize;
  254.         }
  255.     /* put the packed data out */
  256.         dstPtr = packBuf;
  257.         for( jjj = packedSize; jjj > 0; jjj-- )
  258.         {
  259.             *tempPicPtr++ = *dstPtr++;
  260.         }
  261.     }
  262.     DisposPtr( packBuf );
  263.     if( (long)tempPicPtr & (long)0x0001 )        /* do long alignment */
  264.         tempPicPtr++;
  265.     *picPtr = (short *) tempPicPtr;
  266.     return( 0 );
  267. }
  268.  
  269.  
  270. long
  271. PutOutPackedDirectPixData( PixMap *srcBits, short **picPtr )
  272. {
  273. Ptr    srcPtr;
  274. Ptr    dstPtr;
  275. Ptr    packBuf;
  276. Ptr    srcBuf;
  277. Ptr    srcBufPtr;
  278. Ptr    tempPicPtr = (char*) *picPtr;
  279. short packedSize;
  280. short iii, jjj, kkk;
  281. unsigned short    myRowBytes = srcBits->rowBytes & 0x3fff;    
  282. unsigned short    componentRowBytes = myRowBytes>>2;    
  283.  
  284. /* put out PixData */
  285.     if( myRowBytes < 8 )
  286.     { /* no packing */
  287.     short * pixMapPtr = (short *) srcBits->baseAddr;
  288.         for( iii = (myRowBytes*(srcBits->bounds.bottom - srcBits->bounds.top))/2; iii > 0; iii-- )
  289.             *tempPicPtr++ = *pixMapPtr++;
  290.         return( 0 );
  291.     }
  292.  
  293.     packBuf = (Ptr)NewPtr( myRowBytes * 2 );
  294.     if( !packBuf )
  295.         return( -1 );
  296.  
  297. /* allocate a buffer for separating the components */
  298.  
  299.     srcBuf = (Ptr)NewPtr( componentRowBytes*3 );
  300.     if( !srcBuf )
  301.         return( -1 );
  302.  
  303. /* Must use only byte accesses to avoid address errors on 68K class machines */
  304.  
  305.     for( iii = 0; iii < srcBits->bounds.bottom - srcBits->bounds.top; iii++ )
  306.     {
  307.         srcBufPtr = srcBuf;
  308.         for( jjj = 1; jjj <= 3; jjj++ )    /* Do red, green, and blue */
  309.         {
  310.             srcPtr = srcBits->baseAddr + (unsigned long)myRowBytes * iii;
  311.             srcPtr += jjj;    /*point to this component */
  312.             for( kkk = 0; kkk < componentRowBytes; kkk++ )
  313.             {
  314.                 *srcBufPtr++ = *srcPtr;
  315.                 srcPtr += 4;
  316.             }
  317.         }    
  318.  
  319.         dstPtr = packBuf;
  320.         srcBufPtr = srcBuf;
  321.         PackBits( &srcBufPtr, &dstPtr, componentRowBytes*3 );
  322.  
  323.         packedSize = (long)dstPtr - (long)packBuf;
  324.         if( myRowBytes <= 250 )
  325.         { /* put a byte to the picture */
  326.             *tempPicPtr++ = (unsigned char)packedSize;
  327.         }
  328.         else
  329.         { /* put a word to the picture */
  330.             *tempPicPtr++ = (unsigned char)(packedSize>>8);
  331.             *tempPicPtr++ = (unsigned char)packedSize;
  332.         }
  333.     /* put the packed data out */
  334.         dstPtr = packBuf;
  335.         for( kkk = packedSize; kkk > 0; kkk-- )
  336.         {
  337.             *tempPicPtr++ = *dstPtr++;
  338.         }
  339.     }
  340.     DisposPtr( packBuf );
  341.     DisposPtr( srcBuf );
  342.     if( (long)tempPicPtr & (long)0x0001 )        /* do long alignment */
  343.         tempPicPtr++;
  344.     *picPtr = (short *) tempPicPtr;
  345.     return( 0 );
  346. }
  347.